<template>
	<div class="form-section">
		<div v-if="!simpleMode" class="section-title">
			<i class="el-icon-calendar"></i>
			<span>排班设置</span>
			<el-tooltip content="设置该班次的排班规则，支持按周循环排班" placement="right">
				<el-icon class="tooltip-icon"><QuestionFilled /></el-icon>
			</el-tooltip>
			<div class="section-switch">
				<span class="switch-label">启用排班</span>
				<el-switch v-model="scheduleData.ScheduleSettingEnabled" size="small" @change="onScheduleEnabledChange"></el-switch>
			</div>
		</div>

		<div v-if="simpleMode || scheduleData.ScheduleSettingEnabled" class="schedule-settings-container">
			<!-- 生效时间设置 -->
			<div v-if="!simpleMode" class="schedule-time-section">
				<div class="time-setting-item">
					<label class="time-label">
						<i class="el-icon-circle-check"></i>
						生效时间 <span class="required-mark">*</span>
					</label>
					<div class="date-range-picker">
						<el-date-picker v-model="scheduleEffectiveStartDate" type="date" placeholder="开始日期" size="small" class="date-picker" />
						<span class="date-separator">-</span>
						<el-date-picker v-model="scheduleEffectiveEndDate" type="date" placeholder="结束日期" size="small" class="date-picker" />
					</div>
				</div>
			</div>

			<!-- 排班方式设置 -->
			<div v-if="!simpleMode" class="schedule-type-section">
				<div class="schedule-type-header">
					<label class="type-label">排班方式 <span class="required-mark">*</span></label>
					<div class="type-radio-group">
						<el-radio v-model="scheduleData.ScheduleType" label="按周循环">按周循环</el-radio>
					</div>
				</div>

				<div class="cycle-period-setting">
					<label class="cycle-label">循环周期 <span class="required-mark">*</span></label>
					<div class="cycle-input-group">
						<el-input-number v-model="scheduleData.CyclePeriod" :min="1" :max="4" size="small" class="cycle-input" @change="onCyclePeriodChange" />
						<span class="cycle-unit">周</span>
						<span class="cycle-desc">一个周期内最多不能超过4周。</span>
					</div>
				</div>
			</div>

			<!-- 排班策略设置 -->
			<div v-if="!simpleMode" class="schedule-policy-section">
				<!-- 节假日排班设置 -->
				<div class="policy-setting-item">
					<label class="policy-label">
						<i class="el-icon-calendar"></i>
						节假日设置
					</label>
					<div class="policy-switch-group">
						<span class="switch-label">节假日正常排班</span>
						<el-switch v-model="holidayNormalSchedule" size="small" @change="onHolidayScheduleChange"></el-switch>
						<el-tooltip content="开启后，节假日将按照正常工作日进行排班" placement="right">
							<el-icon class="tooltip-icon"><QuestionFilled /></el-icon>
						</el-tooltip>
					</div>
				</div>
			</div>

			<!-- 按周排班表格 - 使用 el-table -->
			<div class="weekly-schedule-table" :style="dynamicColors">
				<el-table :data="scheduleTableData" stripe border style="width: 100%" size="small">
					<el-table-column prop="weekLabel" label="班次周数" width="120" align="center" fixed />
					<el-table-column v-for="day in weekdays" :key="day" :label="day" align="center" min-width="100">
						<template #default="{ row, $index }">
							<div
								class="schedule-cell"
								:class="{
									'is-rest': row[day].type === '休班',
									'is-selected': selectedCells.has(`${$index + 1}-${day}`),
									'is-hovering': hoveringCell === `${$index + 1}-${day}`,
									'is-dragging': isDragging,
									'is-view-mode': props.isViewMode,
								}"
								@mousedown="!props.isViewMode && handleCellMouseDown($index + 1, day, $event)"
								@mouseenter="!props.isViewMode && handleCellMouseEnter($index + 1, day, $event)"
								@mouseleave="!props.isViewMode && (hoveringCell = '')"
								@click="!props.isViewMode && handleCellClick($index + 1, day, $event)"
							>
								<div v-if="row[day].type === '休班'" class="rest-schedule">
									<div class="rest-indicator">
										<el-icon><Plus /></el-icon>
									</div>
									<div class="rest-label">休班</div>
								</div>
								<div v-else-if="row[day].type && row[day].type !== ''" class="work-schedule">
									<div class="schedule-type">{{ row[day].type }}</div>
									<div class="schedule-time">{{ row[day].startTime }}-{{ row[day].endTime }}</div>
								</div>
								<div v-else class="empty-schedule">
									<div class="add-indicator">
										<el-icon><Plus /></el-icon>
									</div>
								</div>
							</div>
						</template>
					</el-table-column>
				</el-table>
			</div>

			<!-- 排班提示信息 -->
			<div class="schedule-info-tip">
				<el-alert title="修改排班后，系统会重新计算近两个月的考勤数据，需要手动同意并后台审查" type="info" :closable="false" show-icon />
			</div>
		</div>

		<!-- 批量班次设置弹窗 -->
		<el-dialog
			v-model="showBatchShiftDialog"
			title="批量设置班次"
			width="500px"
			:modal="true"
			:close-on-click-modal="false"
			:close-on-press-escape="true"
			@close="cancelBatchShiftSelection"
			destroy-on-close
		>
			<div class="batch-shift-dialog" @keydown="handleKeydown">
				<!-- 选择提示信息 -->
				<div class="batch-info">
					<el-icon class="info-icon"><InfoFilled /></el-icon>
					<span>已选择 {{ selectedCells.size }} 个班次位，选择班次后将应用到所有选中的班次位</span>
				</div>

				<!-- 班次选择区域 -->
				<div class="shift-selector">
					<div
						v-for="(shift, index) in shiftTypes"
						:key="shift.value"
						class="shift-item"
						:class="{ 'is-selected': selectedShiftType === shift.label }"
						:tabindex="0"
						@click="selectShift(shift.label)"
						@keydown.enter="selectShift(shift.label)"
						@keydown.space.prevent="selectShift(shift.label)"
						:ref="
							(el: HTMLElement | null) => {
								if (el) shiftOptionRefs[index] = el;
							}
						"
					>
						<div class="shift-content">
							<div class="shift-name">{{ shift.label }}</div>
							<div v-if="shift.time" class="shift-time">{{ shift.time }}</div>
						</div>
					</div>
				</div>
			</div>

			<!-- 操作按钮 -->
			<template #footer>
				<div class="dialog-footer">
					<el-button @click="cancelBatchShiftSelection" :disabled="isApplying">取消</el-button>

					<el-button type="danger" @click="clearSelectedShifts" :disabled="isApplying" :loading="isApplying && currentAction === 'clear'" plain>
						{{ isApplying && currentAction === 'clear' ? '清空中...' : '清空班次' }}
					</el-button>

					<el-button
						type="primary"
						@click="confirmApplyShift"
						:disabled="!selectedShiftType || isApplying"
						:loading="isApplying && currentAction === 'apply'"
					>
						{{ isApplying && currentAction === 'apply' ? '应用中...' : '确认应用' }}
					</el-button>
				</div>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts">
import { computed, watch, onMounted, onUnmounted, ref, nextTick, withDefaults } from 'vue';
import { QuestionFilled, Plus, InfoFilled, Sunny, Moon, Coffee, Delete, Check, Setting, Close } from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus';

// 定义组件属性接口
interface ShiftInfo {
	type: string;
	startTime: string | null;
	endTime: string | null;
}

interface ScheduleData {
	ScheduleSettingEnabled: boolean;
	ScheduleEffectiveStartDate: string | null;
	ScheduleEffectiveEndDate: string | null;
	ScheduleType: string;
	CyclePeriod: number;
	WeeklySchedule: Record<string, Record<string, ShiftInfo>>;
}

// 组件属性定义
interface Props {
	modelValue: ScheduleData;
	simpleMode?: boolean;
	workDays?: string[];
	isViewMode?: boolean;
	displayColor?: string;
}

// 组件事件定义
interface Emits {
	(e: 'update:modelValue', value: ScheduleData): void;
	(e: 'validate'): boolean;
	(e: 'update:workdays', value: string[]): void;
}

const props = withDefaults(defineProps<Props>(), {
	simpleMode: false,
	workDays: () => ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'],
	isViewMode: false,
	displayColor: '#409EFF',
});
const emit = defineEmits<Emits>();

// 本地数据响应式处理
const scheduleData = computed({
	get: () => props.modelValue,
	set: (value: ScheduleData) => emit('update:modelValue', value),
});

// 动态颜色计算
const dynamicColors = computed(() => {
	const baseColor = props.displayColor || '#409EFF';
	return {
		'--work-bg-color': `color-mix(in srgb, ${baseColor} 10%, transparent)`,
		'--work-border-color': baseColor,
		'--work-text-color': baseColor,
		'--work-selected-bg-color': `color-mix(in srgb, ${baseColor} 15%, transparent)`,
		'--work-selected-border-color': baseColor,
		'--work-selected-shadow-color': `color-mix(in srgb, ${baseColor} 20%, transparent)`,
	};
});

// 班次选择器相关状态
const showBatchShiftDialog = ref(false);
const currentWeek = ref(1);
const currentDay = ref('');
const selectedShiftType = ref('');
const isApplying = ref(false);
const currentAction = ref<string>('');
const shiftOptionRefs = ref<HTMLElement[]>([]);

// 点击选择相关状态
const selectedCells = ref<Set<string>>(new Set());
const lastSelectedCell = ref<string>('');
const hoveringCell = ref<string>('');

// 拖拽选择状态
const isDragging = ref(false);
const dragStartCell = ref<string>('');
const dragCurrentCell = ref<string>('');
const dragSelectionCells = ref<Set<string>>(new Set()); // 当前拖拽选择的班次位

// 排班策略设置
const holidayNormalSchedule = ref(false);
const weekendDefaultRest = ref(true);

// 节假日排班变化处理
const onHolidayScheduleChange = (value: boolean) => {
	if (value) {
		ElMessage.success('已开启节假日正常排班，节假日将按工作日排班');
	} else {
		ElMessage.info('已关闭节假日正常排班，节假日将按休息日处理');
	}
};

// 班次类型定义
interface ShiftType {
	value: string;
	label: string;
	time: string | null;
	icon: string;
	iconClass: string;
	startTime?: string | null;
	endTime?: string | null;
}

const shiftTypes = ref<ShiftType[]>([
	{
		value: '班',
		label: '班',
		time: null,
		icon: 'Sunny',
		iconClass: 'day-shift',
		startTime: null,
		endTime: null,
	},

	{
		value: '休班',
		label: '休班',
		time: null,
		icon: 'Plus',
		iconClass: 'rest-shift',
		startTime: null,
		endTime: null,
	},
]);

// 星期数组 - 始终显示全部7天
const weekdays = computed(() => {
	return ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'];
});

// 为 el-table 准备的数据
const scheduleTableData = computed(() => {
	const data = [];
	for (let weekNum = 1; weekNum <= scheduleData.value.CyclePeriod; weekNum++) {
		const rowData: any = {
			weekLabel: `第${weekNum}周`,
		};

		// 为每一天生成数据
		weekdays.value.forEach((day) => {
			rowData[day] = getScheduleForWeekAndDay(weekNum, day);
		});

		data.push(rowData);
	}
	return data;
});

// 生效时间的计算属性
const scheduleEffectiveStartDate = computed<Date | null>({
	get: () => (scheduleData.value.ScheduleEffectiveStartDate ? new Date(scheduleData.value.ScheduleEffectiveStartDate) : null),
	set: (value: Date | null) => {
		const newData = { ...scheduleData.value };
		newData.ScheduleEffectiveStartDate = value ? value.toISOString().split('T')[0] : null;
		scheduleData.value = newData;
	},
});

const scheduleEffectiveEndDate = computed<Date | null>({
	get: () => (scheduleData.value.ScheduleEffectiveEndDate ? new Date(scheduleData.value.ScheduleEffectiveEndDate) : null),
	set: (value: Date | null) => {
		const newData = { ...scheduleData.value };
		newData.ScheduleEffectiveEndDate = value ? value.toISOString().split('T')[0] : null;
		scheduleData.value = newData;
	},
});

// 获取指定周和日期的排班信息
const getScheduleForWeekAndDay = (weekNum: number, day: string) => {
	const weekKey = `week${weekNum}`;
	const weekSchedule = scheduleData.value.WeeklySchedule[weekKey];

	if (weekSchedule && weekSchedule[day]) {
		return weekSchedule[day];
	}

	// 周末默认为休班，工作日默认为空
	if (day === '星期六' || day === '星期日') {
		return { type: '休班', startTime: null, endTime: null };
	}

	// 工作日默认为空
	return { type: '', startTime: null, endTime: null };
};

// 排班启用状态变化处理
const onScheduleEnabledChange = (enabled: boolean) => {
	if (!enabled) {
		// 如果禁用排班设置，清空相关数据
		const newData = { ...scheduleData.value };
		newData.ScheduleEffectiveStartDate = null;
		newData.ScheduleEffectiveEndDate = null;
		newData.ScheduleType = '按周循环';
		newData.CyclePeriod = 4;
		scheduleData.value = newData;
	}
};

// 循环周期变化处理
const onCyclePeriodChange = (value: number) => {
	// 确保周期在合理范围内
	if (value > 4) {
		const newData = { ...scheduleData.value };
		newData.CyclePeriod = 4;
		scheduleData.value = newData;
	}
};

// 鼠标按下开始拖拽选择
const handleCellMouseDown = (week: number, day: string, event: MouseEvent) => {
	// 只读模式下不允许鼠标操作
	if (props.isViewMode) return;

	const cellKey = `${week}-${day}`;

	// 阻止文本选择
	event.preventDefault();

	if (event.ctrlKey || event.metaKey) {
		// Ctrl/Cmd 多选模式：切换当前班次位选中状态
		const isCurrentlySelected = selectedCells.value.has(cellKey);
		if (isCurrentlySelected) {
			selectedCells.value.delete(cellKey);
		} else {
			selectedCells.value.add(cellKey);
		}
		lastSelectedCell.value = cellKey;
	} else if (event.shiftKey && lastSelectedCell.value) {
		// Shift 范围选择模式：选择从上次选中到当前班次位的范围
		selectRange(lastSelectedCell.value, cellKey);
	} else {
		// 开始拖拽选择
		isDragging.value = true;
		dragStartCell.value = cellKey;
		dragCurrentCell.value = cellKey;

		// 清空上次拖拽选择记录
		dragSelectionCells.value.clear();

		// 累加模式：不清除现有选择，直接添加当前班次位
		selectedCells.value.add(cellKey);
		dragSelectionCells.value.add(cellKey);
		lastSelectedCell.value = cellKey;
	}
};

// 鼠标移动时的拖拽选择
const handleCellMouseEnter = (week: number, day: string, event: MouseEvent) => {
	// 只读模式下不允许鼠标操作
	if (props.isViewMode) return;

	const cellKey = `${week}-${day}`;
	hoveringCell.value = cellKey;

	if (isDragging.value && dragStartCell.value) {
		dragCurrentCell.value = cellKey;
		// 使用累加模式选择从开始班次位到当前班次位的矩形范围
		selectDragRange(dragStartCell.value, cellKey);
	}
};

// 鼠标释放结束拖拽
const handleMouseUp = () => {
	if (isDragging.value) {
		const wasDragging = isDragging.value;
		isDragging.value = false;
		dragStartCell.value = '';
		dragCurrentCell.value = '';
		// 不清空 dragSelectionCells，保留本次拖拽的选择记录

		// 如果刚结束拖拽且有选中的班次位，打开班次选择器
		if (wasDragging && selectedCells.value.size > 0) {
			setTimeout(() => {
				showBatchShiftDialog.value = true;
			}, 100); // 稍微延迟确保拖拽状态已更新
		}
	}
};

// 点击直接打开选择器
const handleCellClick = (week: number, day: string, event: MouseEvent) => {
	// 只读模式下不允许点击操作
	if (props.isViewMode) return;

	const cellKey = `${week}-${day}`;

	// 如果不是在拖拽过程中的点击，直接打开选择器
	if (!isDragging.value) {
		// 单选模式：清空其他选择，只选中当前班次位
		selectedCells.value.clear();
		selectedCells.value.add(cellKey);
		lastSelectedCell.value = cellKey;

		// 立即打开班次选择器
		setTimeout(() => {
			openShiftSelector(week, day);
		}, 0);
	}
};

// 拖拽累加选择函数（不清除已有选择）
const selectDragRange = (startCellKey: string, endCellKey: string) => {
	const [startWeek, startDay] = startCellKey.split('-');
	const [endWeek, endDay] = endCellKey.split('-');

	const weekdaysArray = weekdays.value;
	const startWeekNum = parseInt(startWeek);
	const endWeekNum = parseInt(endWeek);
	const startDayIndex = weekdaysArray.indexOf(startDay);
	const endDayIndex = weekdaysArray.indexOf(endDay);

	const minWeek = Math.min(startWeekNum, endWeekNum);
	const maxWeek = Math.max(startWeekNum, endWeekNum);

	// 先移除之前的拖拽选择
	dragSelectionCells.value.forEach((cellKey) => {
		selectedCells.value.delete(cellKey);
	});
	dragSelectionCells.value.clear();

	// 累加选择：添加新的拖拽范围
	for (let week = minWeek; week <= maxWeek; week++) {
		if (week === minWeek && week === maxWeek) {
			// 同一周内的范围选择
			const minDay = Math.min(startDayIndex, endDayIndex);
			const maxDay = Math.max(startDayIndex, endDayIndex);
			for (let dayIndex = minDay; dayIndex <= maxDay; dayIndex++) {
				const cellKey = `${week}-${weekdaysArray[dayIndex]}`;
				selectedCells.value.add(cellKey);
				dragSelectionCells.value.add(cellKey);
			}
		} else if (week === minWeek) {
			// 起始周
			for (let dayIndex = week === startWeekNum ? startDayIndex : 0; dayIndex < weekdaysArray.length; dayIndex++) {
				const cellKey = `${week}-${weekdaysArray[dayIndex]}`;
				selectedCells.value.add(cellKey);
				dragSelectionCells.value.add(cellKey);
			}
		} else if (week === maxWeek) {
			// 结束周
			for (let dayIndex = 0; dayIndex <= (week === endWeekNum ? endDayIndex : weekdaysArray.length - 1); dayIndex++) {
				const cellKey = `${week}-${weekdaysArray[dayIndex]}`;
				selectedCells.value.add(cellKey);
				dragSelectionCells.value.add(cellKey);
			}
		} else {
			// 中间的完整周
			for (let dayIndex = 0; dayIndex < weekdaysArray.length; dayIndex++) {
				const cellKey = `${week}-${weekdaysArray[dayIndex]}`;
				selectedCells.value.add(cellKey);
				dragSelectionCells.value.add(cellKey);
			}
		}
	}
};

// 范围选择函数（清除已有选择）
const selectRange = (startCellKey: string, endCellKey: string) => {
	const [startWeek, startDay] = startCellKey.split('-');
	const [endWeek, endDay] = endCellKey.split('-');

	const weekdaysArray = weekdays.value;
	const startWeekNum = parseInt(startWeek);
	const endWeekNum = parseInt(endWeek);
	const startDayIndex = weekdaysArray.indexOf(startDay);
	const endDayIndex = weekdaysArray.indexOf(endDay);

	const minWeek = Math.min(startWeekNum, endWeekNum);
	const maxWeek = Math.max(startWeekNum, endWeekNum);

	// 清除当前选择
	selectedCells.value.clear();

	for (let week = minWeek; week <= maxWeek; week++) {
		if (week === minWeek && week === maxWeek) {
			// 同一周内的范围选择
			const minDay = Math.min(startDayIndex, endDayIndex);
			const maxDay = Math.max(startDayIndex, endDayIndex);
			for (let dayIndex = minDay; dayIndex <= maxDay; dayIndex++) {
				selectedCells.value.add(`${week}-${weekdaysArray[dayIndex]}`);
			}
		} else if (week === minWeek) {
			// 起始周
			for (let dayIndex = week === startWeekNum ? startDayIndex : 0; dayIndex < weekdaysArray.length; dayIndex++) {
				selectedCells.value.add(`${week}-${weekdaysArray[dayIndex]}`);
			}
		} else if (week === maxWeek) {
			// 结束周
			for (let dayIndex = 0; dayIndex <= (week === endWeekNum ? endDayIndex : weekdaysArray.length - 1); dayIndex++) {
				selectedCells.value.add(`${week}-${weekdaysArray[dayIndex]}`);
			}
		} else {
			// 中间周，全选
			for (let dayIndex = 0; dayIndex < weekdaysArray.length; dayIndex++) {
				selectedCells.value.add(`${week}-${weekdaysArray[dayIndex]}`);
			}
		}
	}
};

// 打开班次选择器
const openShiftSelector = (week: number, day: string) => {
	if (selectedCells.value.size > 1) {
		// 多选模式：打开批量设置对话框
		showBatchShiftDialog.value = true;
	} else {
		// 单选模式：直接设置选中的班次位
		selectedCells.value.clear();
		selectedCells.value.add(`${week}-${day}`);
		showBatchShiftDialog.value = true;
	}
};

// 选择班次（不立即应用）
const selectShift = (shiftType: string) => {
	// 如果点击的是已选中的班次，则取消选择
	if (selectedShiftType.value === shiftType) {
		selectedShiftType.value = '';
	} else {
		selectedShiftType.value = shiftType;
	}
};

// 确认应用班次
const confirmApplyShift = async () => {
	if (!selectedShiftType.value) return;

	try {
		// 显示确认对话框
		await ElMessageBox.confirm(`确定要将 ${selectedCells.value.size} 个班次位的班次设置为"${selectedShiftType.value}"吗？`, '确认操作', {
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			type: 'warning',
		});

		isApplying.value = true;
		currentAction.value = 'apply';

		// 模拟应用延迟（实际应用中可能有API调用）
		await new Promise((resolve) => setTimeout(resolve, 500));

		applyShiftToSelected(selectedShiftType.value);
	} catch {
		// 用户取消操作
	} finally {
		isApplying.value = false;
		currentAction.value = '';
	}
};

// 计算当前设置的工作日列表
const calculateWorkDays = (): string[] => {
	const workDaysSet = new Set<string>();

	// 遍历所有周期的排班数据
	for (let weekNum = 1; weekNum <= scheduleData.value.CyclePeriod; weekNum++) {
		const weekKey = `week${weekNum}`;
		const weekSchedule = scheduleData.value.WeeklySchedule[weekKey];

		if (weekSchedule) {
			weekdays.value.forEach((day) => {
				const daySchedule = weekSchedule[day];
				// 如果这一天设置了班次且不是休班、休或空值，则认为是工作日
				if (daySchedule && daySchedule.type && daySchedule.type !== '休班' && daySchedule.type !== '休' && daySchedule.type !== '') {
					workDaysSet.add(day);
				}
			});
		}
	}

	// 返回工作日数组，保持星期顺序
	const allDays = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'];
	return allDays.filter((day) => workDaysSet.has(day));
};

// 应用班次到选中的班次位
const applyShiftToSelected = (shiftType: string) => {
	const newData = { ...scheduleData.value };

	// 获取班次时间信息
	const shiftInfo = shiftTypes.value.find((s) => s.label === shiftType);

	selectedCells.value.forEach((cellKey) => {
		const [week, day] = cellKey.split('-');
		const weekKey = `week${week}`;

		if (!newData.WeeklySchedule[weekKey]) {
			newData.WeeklySchedule[weekKey] = {} as Record<string, ShiftInfo>;
		}

		newData.WeeklySchedule[weekKey][day] = {
			type: shiftType,
			startTime: shiftInfo?.startTime || null,
			endTime: shiftInfo?.endTime || null,
		};
	});

	scheduleData.value = newData;

	// 计算并发出工作日变化事件
	const currentWorkDays = calculateWorkDays();
	emit('update:workdays', currentWorkDays);

	selectedCells.value.clear();
	showBatchShiftDialog.value = false;
	selectedShiftType.value = '';
	ElMessage.success(`已将选中班次位设置为${shiftType}`);
};

// 取消批量班次选择
const cancelBatchShiftSelection = () => {
	showBatchShiftDialog.value = false;
	selectedCells.value.clear();
	selectedShiftType.value = '';
	isApplying.value = false;
};

// 清除所有选择
const clearAllSelection = () => {
	selectedCells.value.clear();
	selectedShiftType.value = '';
};

// 清空选中班次位的班次
const clearSelectedShifts = async () => {
	try {
		await ElMessageBox.confirm(`确定要清空 ${selectedCells.value.size} 个班次位的班次吗？`, '确认清空', {
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			type: 'warning',
		});

		isApplying.value = true;
		currentAction.value = 'clear';

		// 模拟清空延迟
		await new Promise((resolve) => setTimeout(resolve, 300));

		const newData = { ...scheduleData.value };

		selectedCells.value.forEach((cellKey) => {
			const [week, day] = cellKey.split('-');
			const weekKey = `week${week}`;

			if (!newData.WeeklySchedule[weekKey]) {
				newData.WeeklySchedule[weekKey] = {} as Record<string, ShiftInfo>;
			}

			// 清空班次（设置为空状态）
			newData.WeeklySchedule[weekKey][day] = {
				type: '',
				startTime: null,
				endTime: null,
			};
		});

		scheduleData.value = newData;
		selectedCells.value.clear();
		showBatchShiftDialog.value = false;
		selectedShiftType.value = '';
		ElMessage.success('已清空选中班次位的班次');
	} catch {
		// 用户取消操作
	} finally {
		isApplying.value = false;
		currentAction.value = '';
	}
};

// 键盘导航处理
const handleKeydown = (event: KeyboardEvent) => {
	if (event.key === 'Escape') {
		cancelBatchShiftSelection();
	} else if (event.key === 'Enter' && selectedShiftType.value) {
		confirmApplyShift();
	}
};

// 获取班次图标
const getShiftIcon = (shiftType: string) => {
	const iconMap: Record<string, any> = {
		白班: Sunny,
		夜班: Moon,
		中班: Coffee,
		休班: '',
	};
	return iconMap[shiftType] || '';
};

// 获取班次样式
const getShiftClass = (shiftType: string) => {
	const classMap: Record<string, string> = {
		白班: 'day-shift',
		夜班: 'night-shift',
		中班: 'evening-shift',
		休班: 'rest-shift',
	};
	return classMap[shiftType] || 'rest-shift';
};

// 检查班次位是否被选中
const isCellSelected = (week: number, day: string): boolean => {
	return selectedCells.value.has(`${week}-${day}`);
};

// 表单验证方法
const validateScheduleSettings = (): boolean => {
	if (!scheduleData.value.ScheduleSettingEnabled) {
		return true; // 如果未启用排班设置，验证通过
	}

	// 检查必填字段
	if (!scheduleData.value.ScheduleEffectiveStartDate) {
		ElMessage.error('请选择排班生效开始日期');
		return false;
	}

	if (!scheduleData.value.ScheduleEffectiveEndDate) {
		ElMessage.error('请选择排班生效结束日期');
		return false;
	}

	// 检查日期逻辑
	const startDate = new Date(scheduleData.value.ScheduleEffectiveStartDate);
	const endDate = new Date(scheduleData.value.ScheduleEffectiveEndDate);

	if (startDate >= endDate) {
		ElMessage.error('排班生效结束日期必须晚于开始日期');
		return false;
	}

	return true;
};

// 暴露验证方法给父组件
defineExpose({
	validate: validateScheduleSettings,
});

// 监听验证请求
watch(
	() => emit('validate'),
	() => {
		return validateScheduleSettings();
	}
);

// 监听排班数据变化，计算并发出工作日变化
watch(
	() => scheduleData.value.WeeklySchedule,
	() => {
		const currentWorkDays = calculateWorkDays();
		if (currentWorkDays.length > 0) {
			emit('update:workdays', currentWorkDays);
		}
	},
	{ deep: true }
);

// 组件挂载时添加全局事件监听
onMounted(() => {
	// 添加键盘事件监听
	document.addEventListener('keydown', handleKeydown);
	// 添加全局鼠标事件监听
	document.addEventListener('mouseup', handleMouseUp);
	// 阻止拖拽时选中文本
	document.addEventListener('selectstart', (e) => {
		if (isDragging.value) {
			e.preventDefault();
		}
	});
});

// 组件卸载时清理事件监听
onUnmounted(() => {
	document.removeEventListener('keydown', handleKeydown);
	document.removeEventListener('mouseup', handleMouseUp);
});
</script>

<style scoped lang="scss">
.form-section {
	margin-bottom: 24px;
}

.section-title {
	display: flex;
	align-items: center;
	margin-bottom: 16px;
	font-size: 16px;
	font-weight: 600;
	color: var(--el-text-color-primary);

	i {
		margin-right: 8px;
		color: var(--el-color-primary);
	}

	.tooltip-icon {
		margin-left: 8px;
		color: var(--el-text-color-placeholder);
		cursor: help;
	}

	.section-switch {
		margin-left: auto;
		display: flex;
		align-items: center;
		gap: 8px;

		.switch-label {
			font-size: 14px;
			color: var(--el-text-color-regular);
		}
	}
}

.schedule-settings-container {
	background: var(--el-bg-color);
	border-radius: 8px;
	padding: 20px;
	border: 1px solid var(--el-border-color-light);
}

.schedule-time-section {
	margin-bottom: 24px;

	.time-setting-item {
		display: flex;
		align-items: center;
		gap: 16px;

		.time-label {
			display: flex;
			align-items: center;
			min-width: 120px;
			font-weight: 500;
			color: var(--el-text-color-primary);

			i {
				margin-right: 6px;
				color: var(--el-color-success);
			}

			.required-mark {
				color: var(--el-color-danger);
				margin-left: 2px;
			}
		}

		.date-range-picker {
			display: flex;
			align-items: center;
			gap: 12px;

			.date-picker {
				width: 160px;
			}

			.date-separator {
				color: var(--el-text-color-placeholder);
				font-weight: 500;
			}
		}
	}
}

.schedule-policy-section {
	margin-bottom: 24px;

	.policy-setting-item {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 16px;
		background: var(--el-bg-color);
		border: 1px solid var(--el-border-color-light);
		border-radius: 6px;
		margin-bottom: 12px;

		&:last-child {
			margin-bottom: 0;
		}

		.policy-label {
			display: flex;
			align-items: center;
			font-weight: 500;
			color: var(--el-text-color-primary);
			min-width: 120px;

			i {
				margin-right: 8px;
				color: var(--el-color-primary);
			}
		}

		.policy-switch-group {
			display: flex;
			align-items: center;
			gap: 12px;

			.switch-label {
				font-size: 14px;
				color: var(--el-text-color-regular);
				white-space: nowrap;
			}

			.tooltip-icon {
				color: var(--el-text-color-placeholder);
				cursor: help;
			}
		}
	}
}

.selection-instructions {
	margin-bottom: 16px;

	.instruction-content {
		display: flex;
		align-items: center;
		padding: 12px 16px;
		background: var(--el-color-primary-light-9);
		border: 1px solid var(--el-color-primary-light-7);
		border-radius: 6px;
		font-size: 14px;
		color: var(--el-color-primary);
		gap: 8px;

		.instruction-icon {
			color: var(--el-color-primary);
		}

		.instruction-text {
			font-weight: 500;
		}
	}
}

.schedule-type-section {
	margin-bottom: 24px;

	.schedule-type-header {
		display: flex;
		align-items: center;
		gap: 16px;
		margin-bottom: 16px;

		.type-label {
			min-width: 120px;
			font-weight: 500;
			color: var(--el-text-color-primary);

			.required-mark {
				color: var(--el-color-danger);
				margin-left: 2px;
			}
		}

		.type-radio-group {
			display: flex;
			gap: 16px;
		}
	}

	.cycle-period-setting {
		display: flex;
		align-items: center;
		gap: 16px;

		.cycle-label {
			min-width: 120px;
			font-weight: 500;
			color: var(--el-text-color-primary);

			.required-mark {
				color: var(--el-color-danger);
				margin-left: 2px;
			}
		}

		.cycle-input-group {
			display: flex;
			align-items: center;
			gap: 8px;

			.cycle-input {
				width: 80px;
			}

			.cycle-unit {
				color: var(--el-text-color-regular);
				font-weight: 500;
			}

			.cycle-desc {
				color: var(--el-text-color-placeholder);
				font-size: 12px;
				margin-left: 8px;
			}
		}
	}
}

.weekly-schedule-table {
	margin-bottom: 20px;

	:deep(.el-table) {
		border-radius: 6px;
		border: 1px solid var(--el-border-color-light);

		th {
			background-color: var(--el-table-header-bg-color);
			font-weight: 600;
			border-color: var(--el-border-color-light);
		}

		td {
			padding: 8px;
			vertical-align: middle;
			border-color: var(--el-border-color-lighter);
		}
	}

	// 表格班次位样式
	.schedule-cell {
		position: relative;
		padding: 8px 4px;
		cursor: pointer;
		transition: all 0.2s ease;
		user-select: none;
		min-height: 50px;
		display: flex;
		align-items: center;
		justify-content: center;
		border-radius: 4px;
		border: 1px solid transparent;

		// 拖拽状态
		&.is-dragging {
			cursor: crosshair;
		}

		// 鼠标悬停效果
		&:hover:not(.is-selected),
		&.is-hovering:not(.is-selected) {
			background-color: var(--el-table-header-bg-color);
			border-color: var(--el-border-color);
			cursor: pointer;
		}

		// 只读模式样式
		&.is-view-mode {
			cursor: default !important;

			&:hover:not(.is-selected) {
				background-color: transparent !important;
				border-color: transparent !important;
			}
		}

		// 工作班次选中状态 - 使用动态颜色
		&.is-selected:not(.is-rest) {
			background: var(--work-selected-bg-color, var(--el-color-primary-light-9)) !important;
			border: 1px solid var(--work-selected-border-color, var(--el-color-primary)) !important;
			box-shadow: 0 0 8px 0 var(--work-selected-shadow-color, color-mix(in srgb, var(--el-color-primary) 20%, transparent));
			position: relative;

			// 简洁的右上角标记
			&::before {
				content: '';
				position: absolute;
				top: 0;
				right: 0;
				width: 0;
				height: 0;
				border-style: solid;
				border-width: 0 16px 16px 0;
				border-color: transparent var(--work-selected-border-color, var(--el-color-primary)) transparent transparent;
				border-radius: 0 4px 0 0;
			}

			&::after {
				content: '✓';
				position: absolute;
				top: 1px;
				right: 2px;
				color: white;
				font-size: 9px;
				font-weight: bold;
				z-index: 2;
			}

			.schedule-type {
				color: var(--el-color-primary) !important;
				font-weight: 600;
				background: var(--el-color-primary-light-9) !important;
				border-color: var(--el-color-primary-light-7);
			}

			.schedule-time {
				color: var(--el-color-primary) !important;
				font-weight: 500;
			}
		}

		// 休班状态特殊样式 - Element Plus success色(绿色)
		&.is-rest {
			background: var(--el-fill-color-light);

			&.is-selected {
				background: var(--el-color-success-light-9) !important;
				border: 1px solid var(--el-color-success) !important;
				box-shadow: 0 0 8px 0 color-mix(in srgb, var(--el-color-success) 20%, transparent);

				&::before {
					content: '';
					position: absolute;
					top: 0;
					right: 0;
					width: 0;
					height: 0;
					border-style: solid;
					border-width: 0 16px 16px 0;
					border-color: transparent var(--el-color-success) transparent transparent;
					border-radius: 0 4px 0 0;
				}

				&::after {
					content: '✓';
					position: absolute;
					top: 1px;
					right: 2px;
					color: white;
					font-size: 9px;
					font-weight: bold;
					z-index: 2;
				}

				.rest-label {
					color: var(--el-color-success) !important;
					font-weight: 600;
				}

				.el-icon {
					color: var(--el-color-success) !important;
				}
			}
		}
	}

	.work-schedule {
		text-align: center;
		width: 100%;

		.schedule-type {
			background: var(--work-bg-color, var(--el-color-success-light-9));
			color: var(--work-text-color, var(--el-color-success));
			padding: 6px 10px;
			border-radius: 4px;
			font-size: 12px;
			font-weight: 500;
			white-space: nowrap;
			margin-bottom: 4px;
			transition: all 0.2s ease;
		}

		.schedule-time {
			font-size: 11px;
			color: var(--el-text-color-regular);
			transition: all 0.2s ease;
		}
	}

	.rest-schedule {
		text-align: center;
		color: var(--el-color-success);
		width: 100%;

		.rest-indicator {
			margin-bottom: 4px;

			.el-icon {
				font-size: 18px;
				color: var(--el-color-success);
				transition: all 0.2s ease;
			}
		}

		.rest-label {
			font-size: 12px;
			color: var(--el-color-success);
			font-weight: 500;
			transition: all 0.2s ease;
		}
	}

	.empty-schedule {
		text-align: center;
		width: 100%;
		min-height: 40px;
		padding: 12px 0;
		border: 1px dashed var(--el-border-color-light);
		border-radius: 4px;
		background: var(--el-bg-color-page);
		cursor: pointer;
		transition: all 0.2s ease;

		&:hover {
			border-color: var(--el-color-primary);
			background: var(--el-color-primary-light-9);
		}
	}
}

.schedule-info-tip {
	:deep(.el-alert) {
		border-radius: 6px;
	}
}

.required-mark {
	color: var(--el-color-danger);
}

// 批量设置班次弹窗样式
.batch-shift-dialog {
	.batch-info {
		display: flex;
		align-items: flex-start;
		gap: 8px;
		padding: 16px;
		background: var(--el-table-header-bg-color);
		border-radius: 4px;
		margin-bottom: 20px;
		border-left: 4px solid var(--el-color-primary);

		.info-icon {
			color: var(--el-color-primary);
			font-size: 16px;
			margin-top: 2px;
			flex-shrink: 0;
		}

		span {
			color: var(--el-text-color-regular);
			font-size: 14px;
			line-height: 1.5;
		}
	}

	.shift-selector {
		.shift-item {
			display: flex;
			align-items: center;
			padding: 12px 16px;
			border: 1px solid var(--el-border-color);
			border-radius: 4px;
			margin-bottom: 8px;
			cursor: pointer;
			transition: all 0.2s;
			background: var(--el-bg-color);

			&:hover {
				border-color: var(--el-color-primary);
				background: var(--el-color-primary-light-9);
			}

			&.is-selected {
				border-color: var(--el-color-primary);
				background: var(--el-color-primary-light-9);
				position: relative;

				&::after {
					content: '';
					position: absolute;
					right: 8px;
					top: 50%;
					transform: translateY(-50%);
					width: 16px;
					height: 16px;
					background: var(--el-color-primary);
					border-radius: 50%;
					background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='%23ffffff' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='m13.854 3.646-7.5 7.5a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6 10.293l7.146-7.147a.5.5 0 0 1 .708.708z'/%3e%3c/svg%3e");
					background-size: 10px;
					background-position: center;
					background-repeat: no-repeat;
				}
			}

			.shift-content {
				flex: 1;

				.shift-name {
					font-size: 14px;
					font-weight: 500;
					color: var(--el-text-color-primary);
					margin-bottom: 2px;
				}

				.shift-time {
					font-size: 12px;
					color: var(--el-text-color-placeholder);
				}
			}
		}
	}
}

.dialog-footer {
	display: flex;
	justify-content: flex-end;
	gap: 12px;
}
</style>
